package com.web.surf.sample.eshop.faces.backing.beans;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.web.surf.sample.eshop.database.manager.interfaces.IGoodsService;
import com.web.surf.sample.eshop.database.manager.interfaces.ISectionService;
import com.web.surf.sample.eshop.faces.core.AbstractBean;
import com.web.surf.sample.eshop.faces.interfaces.IPager;
import com.web.surf.sample.eshop.faces.interfaces.IRedirect;
import com.web.surf.sample.eshop.faces.managed.beans.GoodsBean;
import com.web.surf.sample.eshop.faces.managed.beans.GoodsBean.GoodsProperties;
import com.web.surf.sample.eshop.utils.FacesUtil;

/**
 * Data pager
 * 
 * @author SavenkoNV
 */
public class DataPager implements IPager {

	private String sortField;
	private boolean sortAscending;
	private int rowsPerPage;
	private List<AbstractBean> dataList;

	private int totalRows;
	private int currentPage;
	private int firstRow;
	private int totalPages;

	private AbstractBean subcategory;

	private ISectionService sectionService;
	private IGoodsService goodsService;

	/**
	 * Method that presents paged data for using in JSF pages
	 * 
	 * @return paged data
	 */
	public List<AbstractBean> getDataList() {
		if (dataList == null) {
			initPager();
			loadData(0);
		}
		return dataList;
	}

	/**
	 * Method that loads data for pager
	 * 
	 * @param firstRow
	 *            row from which data loading starts
	 */
	private void loadData(int firstRow) {
		String subcategoryId = (String) FacesUtil
				.getSessionMapValue(IRedirect.REDIRECT_LINK);
		subcategory = sectionService.getSubcategoryByID(subcategoryId);
		String sortDirection = sortAscending ? "ASC" : "DESC";
		List<AbstractBean> abstractList = goodsService.getSortedGoodsByPage(
				subcategory, sortField, sortDirection, firstRow, rowsPerPage);
		dataList = new ArrayList<AbstractBean>();
		Iterator<AbstractBean> i = abstractList.iterator();
		while (i.hasNext()) {
			GoodsBean cur = (GoodsBean) i.next();
			dataList.add(cur);
		}
	}

	/**
	 * Calculates total number of pages
	 * 
	 * @return totalPages - total number of presented data pages
	 */
	private int calculateTotalPages() {
		int totalRowsCount = getTotalRows();
		totalPages = (totalRowsCount / rowsPerPage)
				+ ((totalRowsCount % rowsPerPage != 0) ? 1 : 0);
		return totalPages;
	}

	/**
	 * Method that count total number of data rows
	 * 
	 * @return quantity of total rows to be loaded at all pages of pager
	 */
	public int getTotalRows() {
		totalRows = goodsService.getGoodsCountForSubcategory(subcategory);
		return totalRows;
	}

	/**
	 * Initialization of default rows per page, sort field and sort direction of
	 * AbstractPager
	 */
	protected void initPager() {
		firstRow = 0;
		currentPage = 1;
		rowsPerPage = 1;
		sortAscending = true;
		sortField = GoodsProperties.GOODS_PRODUCER.getDatabaseName();
	}

	/**
	 * Executes navigation through pages of pager. Used by PagerNavigator
	 * 
	 * @param firstRow
	 *            first row of current page
	 */
	public void executeNavigation(int firstRow) {
		loadData(firstRow);
	}

	/**
	 * Executes sorting of pages by chosen sort field. Used by PagerSorter
	 * 
	 * @param sortField
	 *            field for sorting
	 * @param sortAscending
	 *            sort direction (ascending or descending)
	 */
	public void executeSorting(String sortField, boolean sortAscending) {
		this.sortAscending = sortAscending;
		this.sortField = sortField;
		loadData(0);
	}

	// Spring setters
	public void setGoodsService(IGoodsService goodsService) {
		this.goodsService = goodsService;
	}

	public void setSectionService(ISectionService sectionService) {
		this.sectionService = sectionService;
	}

	// Navigation setters
	public void setTotalPages(int totalPages) {
		this.totalPages = totalPages;
	}

	public void setCurrentPage(int currentPage) {
		this.currentPage = currentPage;
	}

	public void setFirstRow(int firstRow) {
		this.firstRow = firstRow;
	}

	// Sorting getters
	public String getSortField() {
		return sortField;
	}

	public boolean isSortAscending() {
		return sortAscending;
	}

	// Navigation getters
	public int getTotalPages() {
		return calculateTotalPages();
	}

	public int getFirstRow() {
		return firstRow;
	}

	public int getCurrentPage() {
		return currentPage;
	}

	// Input rows per page methods
	public int getRowsPerPage() {
		return rowsPerPage;
	}

	public void setRowsPerPage(int rowsPerPage) {
		this.rowsPerPage = rowsPerPage;
	}
}